package com.tulele.vtool.handler;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Maps;
import com.tulele.vtool.model.SysGzh;
import com.tulele.vtool.model.UserInfo;
import com.tulele.vtool.model.reqEntity.WxMpSubscribeMessageInfo;
import com.tulele.vtool.model.respEntity.RespData;
import com.tulele.vtool.model.respEntity.ReturnCode;
import com.tulele.vtool.service.IUserInfoService;
import com.tulele.vtool.service.SysGzhService;
import com.tulele.vtool.utils.HttpClientUtils;
import com.tulele.vtool.wechat.service.WeixinServiceDL;
import com.tulele.vtool.wechat.service.WeixinServiceMap;
import com.tulele.vtool.wechat.token.server.AccessTokenMemServer;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Header;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.net.URI;
import java.util.HashMap;
import java.util.Map;

@RestController
@Slf4j
@RequestMapping("/wechat")
public class SubscribeMessageHandler {
    /**
     * 微信发送订阅消息Url
     */
    private final static String SUBSCRIBE_MESSAGE_URL = "https://api.weixin.qq.com/cgi-bin/message/subscribe/bizsend?access_token=ACCESS_TOKEN";

    @Autowired
    private IUserInfoService userInfoService;

    @Autowired
    private SysGzhService sysGzhService;

    @Autowired
    private ObjectFactory<WeixinServiceDL> objectFactory;

    /**
     * 微信公众号发送统一订阅消息
     * @param userId 用户ID
     * @param identifying 公众号标识
     * @param wxMpSubscribeMessageInfo 封装实体
     * @return
     */
    @PostMapping(value = "/sendSubscribeMessage", produces = "application/json;charset=UTF-8")
    public RespData sendSubscribeMessage(@RequestHeader("userId") String userId,
                                         @RequestHeader("identifying") String identifying,
                                         @RequestBody WxMpSubscribeMessageInfo wxMpSubscribeMessageInfo) {
        if (StringUtils.isBlank(userId) || !StringUtils.isNumeric(userId) || StringUtils.isBlank(identifying) || wxMpSubscribeMessageInfo == null) {
            RespData respData = new RespData();
            respData.setCode(ReturnCode.CLIENT_ERROR);
            respData.setMsg("参数异常");
            return respData;
        }

        // 获取公众号信息
        /*SysGzh sysGzh = sysGzhService.getPlatformSysInfo(identifying).getSysGzh();
        String appId = sysGzh.getAppId();// appid
        String secret = sysGzh.getSecret();// secret

        // AccessToken 中控服务器获取 AccessToken
        String accessToken = AccessTokenMemServer.getAccessToken(identifying, appId, secret);
        String url = SUBSCRIBE_MESSAGE_URL.replace("ACCESS_TOKEN", accessToken);*/



        WeixinServiceDL weixinService = WeixinServiceMap.getWeixinService(identifying);
        if (weixinService == null) {
            weixinService = objectFactory.getObject();
            weixinService.reSetConfigStorage(identifying);
            WeixinServiceMap.putWeixinService(identifying, weixinService);
        }

        String accessToken = "";

        try {
            accessToken = weixinService.getAccessToken();
        } catch (WxErrorException e) {
            e.printStackTrace();
            log.error("微信回调结果异常,异常原因{}", e.getMessage());
            RespData respData = new RespData();
            respData.setCode(ReturnCode.SERVER_ERROR);
            respData.setMsg(e.getMessage());
            return respData;
        }
        String url = SUBSCRIBE_MESSAGE_URL.replace("ACCESS_TOKEN", accessToken);


        // 获取用户 openid
        UserInfo userInfo = userInfoService.getUserBaseInfo(Integer.valueOf(userId));
        wxMpSubscribeMessageInfo.setToUser(userInfo.getOpenId());

        Map<String, Object> params = new HashMap<>();
        params.put("touser", wxMpSubscribeMessageInfo.getToUser());
        params.put("template_id", wxMpSubscribeMessageInfo.getTemplateId());
        // 跳转页面
        if (StringUtils.isNotBlank(wxMpSubscribeMessageInfo.getPage())) {
            params.put("page", wxMpSubscribeMessageInfo.getPage());
        }
        // 跳转小程序页面
        WxMpSubscribeMessageInfo.MiniProgram miniProgram = wxMpSubscribeMessageInfo.getMiniProgram();
        if (miniProgram != null && StringUtils.isNotBlank(miniProgram.getAppid()) && StringUtils.isNotBlank(miniProgram.getPagepath())) {
            params.put("miniprogram", wxMpSubscribeMessageInfo.getMiniProgram());
        }
        params.put("data", wxMpSubscribeMessageInfo.getData());

        String responseText = "";
        /*try {
            responseText = HttpClientUtils.sendPost(url, params);
        } catch (Exception e) {
            RespData respData = new RespData();
            respData.setCode(ReturnCode.SERVER_ERROR);
            respData.setMsg(e.getMessage());
            return respData;
        }*/

        // 创建Client
        CloseableHttpClient client = HttpClients.createDefault();
        // 创建HttpPost对象
        HttpPost httpPost = new HttpPost();
        try {
            // 设置请求地址
            httpPost.setURI(new URI(url));
            // 设置请求头
            /*if (headers != null) {
                Header[] allHeader = new BasicHeader[headers.size()];
                int i = 0;
                for (Map.Entry<String, String> entry : headers.entrySet()) {
                    allHeader[i] = new BasicHeader(entry.getKey(), entry.getValue());
                    i++;
                }
                httpPost.setHeaders(allHeader);
            }*/
            // 设置实体
            httpPost.setEntity(new StringEntity(JSON.toJSONString(params), "utf-8"));
            // 发送请求,返回响应对象
            CloseableHttpResponse response = client.execute(httpPost);

            // 获取响应状态
            int status = response.getStatusLine().getStatusCode();
            if (status == HttpStatus.SC_OK) {
                // 获取响应数据
                responseText = EntityUtils.toString(response.getEntity());
            } else {
                log.error("响应失败，状态码：" + status);
            }

        } catch (Exception e) {
            log.error("发送post请求失败", e);
        } finally {
            httpPost.releaseConnection();
        }
        log.info("[responseText] = {}", responseText);

        HashMap<String, Object> resutlMap = Maps.newHashMapWithExpectedSize(10);
        resutlMap.put("result", responseText);

        RespData respData = new RespData();
        respData.setCode(ReturnCode.NORMAL_SUCC);
        respData.setMsg("成功");
        respData.setData(resutlMap);
        return respData;
    }
}
